package com.abigdreamer.im.client.module.main.weather;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/**
 * 
 * 天气查询. 推荐使用此 google service 查询<br/>
 * 
 * 直接调用getWeather（返回类型为Map<String, Map<String, String>>）即可
 */
public class GoogleWeather {

	/**
	 * 
	 * 使用 google 查询天气<br/>
	 * 上海: http://www.google.com/ig/api?hl=zh_cn&weather=shanghai
	 * 
	 * @param city
	 *            城市拼音, 如 北京: beijing
	 * @return wuhan : 2010-02-27 天气： 晴, 温度： 8 － 20℃, 湿度： 88%, 风向： 东南、风速：4 米/秒
	 */

	public static String getweather(String city) {

		StringBuilder sbd = new StringBuilder();

		try {
			String ur = "http://www.google.com/ig/api?hl=zh_cn&weather=";
			URL url = new URL(ur + city);
			InputStream in = url.openStream();

			// 解决乱码问题
			ByteArrayOutputStream bos = new ByteArrayOutputStream();

			int i = -1;
			while ((i = in.read()) != -1)
				bos.write(i);

			// 使用 utf-8 编码. 若不使用则默认会使用本地编码 GB18030, 则会有乱码
			InputStream inp = new ByteArrayInputStream(bos.toString().getBytes("utf-8"));
			// 读取流
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inp);

			// 城市:
			sbd.append(city).append(" : ");
			NodeList n1 = getNode(doc, "forecast_information", 0);

			// 日期
			sbd.append(getAttributeValue(n1, 4, 0) + " ");

			NodeList n2 = getNode(doc, "current_conditions", 0);
			System.out.println("天气: " + getAttributeValue(n2, 0, 0));
			System.out.println(getAttributeValue(n2, 3, 0));
			System.out.println(getAttributeValue(n2, 5, 0));

			// 天气
			sbd.append("天气： " + getAttributeValue(n2, 0, 0) + ", ");

			NodeList n3 = getNode(doc, "forecast_conditions", 0);

			// 最低气温
			sbd.append("温度： " + getAttributeValue(n3, 1, 0));

			sbd.append(" － ");

			// 最高气温
			sbd.append(getAttributeValue(n3, 2, 0) + "℃, ");

			// 湿度
			sbd.append(getAttributeValue(n2, 3, 0) + ", ");

			// 风向
			sbd.append(getAttributeValue(n2, 5, 0));
		} catch (Exception e) {
			sbd.append("获取天气失败或不存在此城市");
		}

		return sbd.toString();
	}

	/**
	 * 
	 * 获取节点集合
	 * 
	 * @param doc
	 *            : Doument 对象
	 * @param tagName
	 *            : 节点名
	 * @param index
	 *            : 找到的第几个
	 * @return
	 */
	private static NodeList getNode(Document doc, String tagName, int index) {

		return doc.getElementsByTagName(tagName).item(index).getChildNodes();
	}

	/**
	 * 
	 * 获取节点内容
	 * 
	 * @param node
	 *            : nodelist
	 * @param index
	 *            : 节点索引, 也可使用 getNamedItem(String name) 节点名查找
	 * @param item
	 *            : 属性的索引
	 * @return
	 */
	private static String getAttributeValue(NodeList node, int index, int item) {

		return node.item(index).getAttributes().item(item).getNodeValue();
	}

	/**
	 * 根据城市名字获得该城市的天气预报
	 * 
	 * @param city
	 * @return
	 */
	public static Map<String, Map<String, String>> getWeather(String city) {

		Map<String, Map<String, String>> weatherReport = new HashMap<String, Map<String, String>>();

		Map<String, String> weatherResult = null;

		NodeList nodeList = null;

		try {
			String ur = "http://www.google.com/ig/api?hl=zh_cn&weather=";

			URL url = new URL(ur + city);

			InputStream in = url.openStream();

			// 解决乱码问题
			ByteArrayOutputStream bos = new ByteArrayOutputStream();

			int i = -1;
			while ((i = in.read()) != -1)
				bos.write(i);
			// 使用 utf-8 编码. 若不使用则默认会使用本地编码 GB18030,
			// 则会有乱码，注意一定要先转成gbk即toString("GBK")
			InputStream inp = new ByteArrayInputStream(bos.toString("GBK").getBytes("utf-8"));

			// 读取流
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inp);

			// forecast_information
			nodeList = getNode(doc, "forecast_information", 0);

			weatherResult = new HashMap<String, String>();
			weatherResult.put("city", getAttributeValue(nodeList, 0, 0));
			weatherResult.put("postal_code", getAttributeValue(nodeList, 1, 0));
			weatherResult.put("latitude_e6", getAttributeValue(nodeList, 2, 0));
			weatherResult.put("longitude_e6", getAttributeValue(nodeList, 3, 0));
			weatherResult.put("forecast_date", getAttributeValue(nodeList, 4, 0));
			weatherResult.put("current_date_time", getAttributeValue(nodeList, 5, 0));
			weatherResult.put("unit_system", getAttributeValue(nodeList, 6, 0));
			weatherReport.put("forecast_information", weatherResult);

			// 当天信息
			nodeList = getNode(doc, "current_conditions", 0);
			weatherResult = new HashMap<String, String>();
			weatherResult.put("condition", getAttributeValue(nodeList, 0, 0));
			weatherResult.put("temp_f", getAttributeValue(nodeList, 1, 0));
			weatherResult.put("temp_c", getAttributeValue(nodeList, 2, 0));
			weatherResult.put("humidity", getAttributeValue(nodeList, 3, 0));
			weatherResult.put("icon", getAttributeValue(nodeList, 4, 0));
			weatherResult.put("wind_condition", getAttributeValue(nodeList, 5, 0));
			weatherReport.put("current_conditions", weatherResult);

			// 预测
			NodeList forecastList = doc.getElementsByTagName("forecast_conditions");
			for (int j = 0; j < forecastList.getLength(); j++) {
				nodeList = forecastList.item(j).getChildNodes();
				weatherResult = new HashMap<String, String>();
				weatherResult.put("day_of_week", getAttributeValue(nodeList, 0, 0));
				weatherResult.put("low", getAttributeValue(nodeList, 1, 0));
				weatherResult.put("high", getAttributeValue(nodeList, 2, 0));
				weatherResult.put("icon", getAttributeValue(nodeList, 3, 0));
				weatherResult.put("condition", getAttributeValue(nodeList, 4, 0));
				weatherReport.put("forecast_conditions" + (j + 1), weatherResult);
			}

		} catch (Exception e) {
			// 获取天气失败或不存在此城市
			weatherReport = null;
		}

		return weatherReport;
	}

	/**
	 * 打印Map结果
	 */
	public static void printWeatherResult(Map<String, String> keyValues) {

		Set<String> keys = keyValues.keySet();

		for (String key : keys) {
			System.out.println(key + ":" + keyValues.get(key));
		}
	}

	/**
	 * 测试Main方法
	 */
	public static void main(String[] args) throws UnsupportedEncodingException {

		// 测试同一ip是否有限制
		for (int i = 0; i < 2; i++) {

			Map<String, Map<String, String>> weatherReport = getWeather("nanjing");

			if (null != weatherReport) {

				Map<String, String> keyValues = weatherReport.get("current_conditions");

				System.out.println("******************当前天气***********************");
				printWeatherResult(keyValues);
				keyValues = weatherReport.get("forecast_conditions1");

				System.out.println("******************第一天***********************");
				printWeatherResult(keyValues);
				keyValues = weatherReport.get("forecast_conditions2");

				System.out.println("******************第二天***********************");
				printWeatherResult(keyValues);
				keyValues = weatherReport.get("forecast_conditions3");

				System.out.println("******************第三天***********************");
				printWeatherResult(keyValues);
				keyValues = weatherReport.get("forecast_conditions4");

				System.out.println("******************第四天***********************");
				printWeatherResult(keyValues);

			} else {
				System.out.print("获取天气失败或不存在此城市");
			}

		}

	}

}